home *** CD-ROM | disk | FTP | other *** search
/ Aminet 45 / Aminet 45 (2001)(GTI - Schatztruhe)[!][Oct 2001].iso / Aminet / dev / gui / FoxGuiSource.lha / FoxLibSource / OutputBox.c < prev    next >
C/C++ Source or Header  |  2001-07-07  |  13KB  |  376 lines

  1. /* FoxGUI - The fast, flexible, free Amiga GUI system
  2.     Copyright (C) 2001 Simon Fox (Foxysoft)
  3.  
  4. This library is free software; you can redistribute it and/ormodify it under the terms of the GNU Lesser General PublicLicense as published by the Free Software Foundation; eitherversion 2.1 of the License, or (at your option) any later version.This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULesser General Public License for more details.You should have received a copy of the GNU Lesser General PublicLicense along with this library; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  5. Foxysoft: www.foxysoft.co.uk      Email:simon@foxysoft.co.uk                */
  6.  
  7. /******************************************************************************
  8.  * Shared library code.  Cannot call functions which use exit() such as:
  9.  * printf(), fprintf()
  10.  *
  11.  * Otherwise:
  12.  * The linker returns "__XCEXIT undefined" and the program will fail.
  13.  * This is because you must not exit() a library!
  14.  *
  15.  * Also:
  16.  * proto/exec.h must be included instead of clib/exec_protos.h and
  17.  * __USE_SYSBASE must be defined.
  18.  *
  19.  * Otherwise:
  20.  * The linker returns "Absolute reference to symbol _SysBase" and the
  21.  * library crashes.  Presumably the same is true for the other protos.
  22.  ******************************************************************************/
  23.  
  24. #define __USE_SYSBASE
  25.  
  26. #include <proto/mathieeedoubbas.h>
  27. #include <math.h>
  28. #include <string.h>
  29.  
  30. #include "/FoxInclude/foxgui.h"
  31. #include "FoxGuiTools.h"
  32.  
  33. #include <proto/exec.h>
  34. #include <proto/intuition.h>
  35.  
  36. static void TruncateOBText(OutputBox *ob)
  37.     {
  38.     int MaxLen = ob->WidgetData->flags & THREED ? ob->points[0] - 2 : ob->points[2] - 1;
  39.     TruncateIText(&ob->IText, ob->text, MaxLen, ob->WidgetData->flags);
  40.     }
  41.  
  42. static void RefreshOutputBox(OutputBox *p)
  43.     {
  44.     if (p->hidden == 0)
  45.         {
  46.         // Print the text
  47.         PrintIText(p->win->Win->RPort, &(p->IText), 0, 0);
  48.  
  49.         // Refresh the border incase the text has trashed it.
  50.         DrawBorder(p->win->Win->RPort, &(p->lborder), 0, 0);
  51.         }
  52.     }
  53.  
  54. void FOXLIB SetOutputBoxText(REGA0 OutputBox *p, REGA1 char *text)
  55.    {
  56.    Diagnostic("SetOutputBoxText", ENTER, TRUE);
  57.  
  58.     if (p && text)
  59.         {
  60.         int PixLen = p->WidgetData->flags & THREED ? p->points[0] + 2 : p->points[2] + 1;
  61.  
  62.         if (p->hidden == 0)
  63.             {
  64.             // Un-print the old text
  65.             int penhold = p->IText.FrontPen;
  66.             p->IText.FrontPen = p->win->Win->RPort->BgPen;
  67.             PrintIText(p->win->Win->RPort, &p->IText, 0, 0);
  68.             p->IText.FrontPen = penhold;
  69.             }
  70.  
  71.         // Prepare the new text.
  72.         if (strlen(text) > p->len)
  73.             { // p->text[0] is used for storing the trunc char.
  74.             strncpy(&p->text[1], text, p->len);
  75.             p->text[p->len + 1] = 0;
  76.             /*    The text has been truncated but we're not storing the trunc char because the text is too
  77.                 long for the buffer.  We store the trunc char if the text fits in the buffer but not in
  78.                 the screen space available. */
  79.             }
  80.         else
  81.             strcpy(&p->text[1], text);
  82.         p->text[0] = 0;
  83.  
  84.         TruncateOBText(p);
  85.  
  86.         if (p->WidgetData->flags & JUSTIFY_LEFT)
  87.             p->IText.LeftEdge = p->lborder.LeftEdge + (p->WidgetData->flags & THREED ? 2 : 1);
  88.         else if (p->WidgetData->flags & JUSTIFY_RIGHT)
  89.             p->IText.LeftEdge = p->lborder.LeftEdge + PixLen - (p->WidgetData->flags & THREED ? 3 : 2) - IntuiTextLength(&p->IText);
  90.         else // JUSTIFY_CENTRE
  91.             p->IText.LeftEdge = ((PixLen - IntuiTextLength(&p->IText)) / 2) + p->lborder.LeftEdge - 1;
  92.  
  93.         // Print the new text
  94.         RefreshOutputBox(p);
  95.  
  96.        Diagnostic("SetOutputBoxText", EXIT, TRUE);
  97.         return;
  98.         }
  99.       Diagnostic("SetOutputBoxText", EXIT, FALSE);
  100.    }
  101.  
  102. BOOL ShowOutputBox(OutputBox *p)
  103.     {
  104.     Diagnostic("ShowOutputBox", ENTER, TRUE);
  105.     if (p)
  106.         {
  107.         if (p->hidden == 1) // The output box is really hidden
  108.             {
  109.             if ((!ISGUIWINDOW(p->WidgetData->Parent)) && ((Frame *) p->WidgetData->Parent)->hidden != 0)
  110.                 p->hidden = -1; // The output box is in a hidden frame and will remain hidden
  111.             else
  112.                 p->hidden = 0;
  113.             }
  114.         if (p->hidden == 0)
  115.             RefreshOutputBox(p);
  116.         return Diagnostic("ShowOutputBox", EXIT, TRUE);
  117.         }
  118.     return Diagnostic("ShowOutputBox", EXIT, FALSE);
  119.     }
  120.  
  121. void FOXLIB SetOutputBoxCols(REGA0 OutputBox *ob, REGD0 int Bcol, REGD1 int Tcol, REGD2 BOOL refresh)
  122.     {
  123.     if (ob)
  124.         {
  125.         ob->Bcol = Bcol;
  126.         ob->Tcol = Tcol;
  127.         ob->IText.FrontPen = ob->Tcol;
  128.         if (!(ob->WidgetData->flags & THREED))
  129.             ob->lborder.FrontPen = Bcol;
  130.         if (refresh)
  131.             RefreshOutputBox(ob);
  132.         }
  133.     }
  134.  
  135. void ResizeOutputBox(OutputBox *ob, int x, int y, int len, BOOL eraseold)
  136.     {
  137.     int fontheight = ob->font ? ob->font->ta_YSize : ob->win->Win->RPort->TxHeight;
  138.  
  139.     /*    If the output box is in a coloured frame then no need to blank it because the parent frame will
  140.         blank it's entire contents. */
  141.     if (eraseold && GetBackCol(ob->WidgetData->Parent) == ob->win->Win->RPort->BgPen)
  142.         {
  143.         int penhold;
  144.  
  145.         AreaBlank(ob->win->Win->RPort, ob->lborder.LeftEdge, ob->lborder.TopEdge, (ob->WidgetData->flags & THREED ?
  146.                 ob->points[12] : ob->points[2]) + 1, fontheight + 2);
  147.         /*    Incase the text in the output box (which doesn't necessarily get clipped) extends beyond the
  148.             box itself, we'd better blank it. */
  149.         penhold = ob->IText.FrontPen;
  150.         ob->IText.FrontPen = ob->win->Win->RPort->BgPen;
  151.         PrintIText(ob->win->Win->RPort, &ob->IText, 0, 0);
  152.         ob->IText.FrontPen = penhold;
  153.         }
  154.  
  155.     if (ob->WidgetData->flags & THREED)
  156.         MakeBevel(&ob->lborder, &ob->dborder, ob->points, x, y, len, fontheight + 2, TRUE);
  157.     else
  158.         {
  159.         ob->points[2] = ob->points[4] = len - 1; /* 0 to len-1 makes len pixels */
  160.         ob->lborder.LeftEdge = x;
  161.         ob->lborder.TopEdge = y;
  162.         }
  163.     ob->IText.TopEdge = y + 1;
  164.     // Must truncate before setting the left edge so that IntuiTextLength returns the correct result.
  165.     TruncateOBText(ob);
  166.     if (ob->WidgetData->flags & JUSTIFY_LEFT)
  167.         ob->IText.LeftEdge = x + (ob->WidgetData->flags & THREED ? 2 : 1);
  168.     else if (ob->WidgetData->flags & JUSTIFY_RIGHT)
  169.         ob->IText.LeftEdge = x + len - (ob->WidgetData->flags & THREED ? 3 : 2) - IntuiTextLength(&ob->IText);
  170.     else // JUSTIFY_CENTRE
  171.         ob->IText.LeftEdge = ((len - IntuiTextLength(&ob->IText)) / 2) + x - 1;
  172.  
  173.     ob->WidgetData->left = x;
  174.     ob->WidgetData->top = y;
  175.     ob->WidgetData->width = len;
  176.     ob->WidgetData->height = fontheight + 2;
  177.     }
  178.  
  179. /*    The top, left hand corner of the outputbox border will be at the EXACT
  180.     position specified in the x and y parameters passed to this function.
  181.  
  182.     The coordinates of the border, the pre-text and the post-text for a
  183.     new edit box are identical to those of an output box which is created
  184.     with the same parameters.  This has been THOROUGHLY tested and works
  185.     whether or not the window has a title bar and independantly of whether
  186.     or not the output box has a border.
  187.  
  188.     DO NOT CHANGE ONE WITHOUT CHANGING THE OTHER - PREFERABLY DON'T CHANGE! */
  189.  
  190. OutputBox* FOXLIB MakeOutputBox(REGA0 void *parent, REGD0 int x, REGD1 int y, REGD2 int width, REGD3 int len,
  191.         REGD4 int id, REGA1 char *InitialValue, REGD5 long flags, REGA2 void *extension)       /* Tcol must be between 0 & 7 */
  192.    {
  193.     GuiWindow *Parent = parent; // May not actually be a guiwindow.
  194.     int fontheight;
  195.    OutputBox *ob;
  196.     GuiWindow *win;
  197.     Frame *ParentFrame = NULL;
  198.    Diagnostic("MakeOutputBox", ENTER, TRUE);
  199.  
  200.    if (!(Parent && ( (len && width) || (flags & OB_PRE) || (flags & OB_POST) || (flags & S_FONT_SENSITIVE) ) ))
  201.       {
  202.       Diagnostic("MakeOutputBox", EXIT, FALSE);
  203.       return NULL;
  204.       }
  205.  
  206.    ob = (OutputBox *) GuiMalloc(sizeof(OutputBox), MEMF_CLEAR);
  207.    if (!ob)
  208.       {
  209.       Diagnostic("MakeOutputBox", EXIT, FALSE);
  210.       return NULL;
  211.       }
  212.    ob->WidgetData = (Widget *) GuiMalloc(sizeof(Widget), MEMF_CLEAR);
  213.    if (!ob->WidgetData)
  214.       {
  215.         GuiFree(ob);
  216.       Diagnostic("MakeOutputBox", EXIT, FALSE);
  217.       return NULL;
  218.       }
  219.  
  220.     if (flags & S_FONT_SENSITIVE)
  221.         width = GuiTextLength(InitialValue, &GuiFont) + (flags & THREED ? 4 : 2);
  222.  
  223.     if (!ISGUIWINDOW(Parent))
  224.         {
  225.         if (Parent->WidgetData->ObjectType == FrameObject)
  226.             {
  227.             ParentFrame = (Frame *) Parent;
  228.             x += ParentFrame->button.LeftEdge;
  229.             y += ParentFrame->button.TopEdge;
  230.             win = (GuiWindow *) ParentFrame->button.UserData;
  231.             }
  232.         else
  233.             {
  234.             GuiWindow *Holder = Parent, *LastChild;
  235.             ob->WidgetData->ParentControl = Parent;
  236.             // The parent is not a frame or a window so we're creating pre or post text for the parent.
  237.  
  238.             LastChild = ((Frame *) ob->WidgetData->ParentControl)->WidgetData->ChildWidget;
  239.             if (LastChild == NULL)
  240.                 ((Frame *) ob->WidgetData->ParentControl)->WidgetData->ChildWidget = ob;
  241.             else
  242.                 {
  243.                 while (LastChild->WidgetData->NextWidget)
  244.                     LastChild = LastChild->WidgetData->NextWidget;
  245.                 LastChild->WidgetData->NextWidget = ob;
  246.                 }
  247.             // Find out what type of object the parent resides in.
  248.             while (Holder->WidgetData->ObjectType != FrameObject && Holder->WidgetData->ObjectType != WindowObject)
  249.                 Holder = Holder->WidgetData->Parent;
  250.             if (Holder->WidgetData->ObjectType == FrameObject)
  251.                 {
  252.                 ParentFrame = (Frame *) Holder;
  253.                 win = (GuiWindow *) ParentFrame->button.UserData;
  254.                 }
  255.             else
  256.                 win = (GuiWindow *) Holder;
  257.             // Now calculate the x and y coordinates of the label based on the label text and the size and position
  258.             // of the parent object.
  259.             width = GuiTextLength(InitialValue, &GuiFont) + (flags & THREED ? 4 : 2);
  260.             y = Parent->WidgetData->top;
  261.             len = strlen(InitialValue) + 1;
  262.             if (flags & OB_POST)
  263.                 {
  264.                 x = Parent->WidgetData->left + Parent->WidgetData->width + 4;
  265.                 if (Parent->WidgetData->ObjectType == DDListBoxObject)
  266.                     x += DD_LIST_BOX_BUTTON_WIDTH;
  267.                 }
  268.             else // OB_PRE
  269.                 x = Parent->WidgetData->left - width - (flags & THREED ? 3 : 1);
  270.             if (flags & JUSTIFY_RIGHT)
  271.                 flags -= JUSTIFY_RIGHT;
  272.             if (flags & JUSTIFY_LEFT)
  273.                 flags -= JUSTIFY_LEFT;
  274.             Parent = Holder;    // !!! Temporary - so that outputbox gets refreshed when necessary (e.g. when frame is shown after
  275.                                     // being hidden).  Can be removed when parents refresh their children.
  276.             }
  277.         }
  278.     else
  279.         win = (GuiWindow *) Parent;
  280.  
  281.     ob->WidgetData->ObjectType = OutputBoxObject;
  282.     ob->WidgetData->NextWidget = NULL;
  283.     ob->WidgetData->ChildWidget = NULL;
  284.    ob->len = min(len, MAX_EDIT_BOX_LEN);
  285.     /*    Allocate space for two extra chars.  The first is the usual NULL terminator, the second is for
  286.         holding a truncation character. */
  287.     if (!(ob->text = (char *) GuiMalloc((ob->len + 2) * sizeof(char), 0)))
  288.       {
  289.         GuiFree(ob->WidgetData);
  290.         GuiFree(ob);
  291.       Diagnostic("MakeOutputBox", EXIT, FALSE);
  292.       return NULL;
  293.       }
  294.     // trunc char = first char = 0.
  295.     ob->text[0] = ob->text[1] = 0;
  296.     ob->font = CopyFont(&GuiFont);
  297.     if (ob->font == NULL)
  298.    {
  299.          GuiFree(ob->text);
  300.         GuiFree(ob->WidgetData);
  301.       GuiFree(ob);
  302.          Diagnostic("MakeOutputBox", EXIT, FALSE);
  303.       return NULL;
  304.       }
  305.     fontheight = ob->font->ta_YSize;
  306.     ob->WidgetData->Parent = Parent;
  307.    ob->win = win;
  308.     if (ParentFrame && ParentFrame->hidden != 0)
  309.         ob->hidden = -1;
  310.     else
  311.         ob->hidden = 0;
  312.     SetOutputBoxCols(ob, Gui.BorderCol, Gui.TextCol, FALSE);
  313.    ob->id = id;
  314.     if (ParentFrame && (flags & S_AUTO_SIZE) && !(ParentFrame->WidgetData->flags & S_AUTO_SIZE))
  315.         flags ^= S_AUTO_SIZE;
  316.    ob->WidgetData->flags = flags;
  317.  
  318.     if (flags & S_AUTO_SIZE)
  319.         {
  320.         if (!(ob->WidgetData->os = (OriginalSize *) GuiMalloc(sizeof(OriginalSize), 0)))
  321.             {
  322.             GuiFree(ob->text);
  323.             GuiFree(ob->WidgetData);
  324.             GuiFree(ob);
  325.             Diagnostic("MakeOutputBox", EXIT, FALSE);
  326.          return NULL;
  327.             }
  328.         ob->WidgetData->os->left = x;
  329.         ob->WidgetData->os->top = y;
  330.         ob->WidgetData->os->width = width;
  331.         ob->WidgetData->os->height = fontheight + 2;
  332.         }
  333.     else
  334.         ob->WidgetData->os = NULL;
  335.  
  336.     if (!(flags & THREED))
  337.         {
  338.        ob->points[5] = ob->points[7] = fontheight + 1; /* 0 to fontheight+1 makes fontheight+2 */
  339.        ob->lborder.Count = (flags & NO_BORDER ? 0 : 5);
  340.        ob->lborder.DrawMode = JAM1;
  341.        ob->lborder.XY = ob->points;
  342.         }
  343.     ob->IText.DrawMode = JAM1;
  344.     ob->IText.ITextFont = ob->font;
  345.     ob->IText.IText = &ob->text[1]; // (ob->text[0] is used for storing the trunc char)
  346.     ob->IText.NextText = NULL;
  347.  
  348.     ResizeOutputBox(ob, x, y, width, FALSE);
  349.  
  350.    ob->next = Gui.FirstOutputBox;
  351.    if (Gui.FirstOutputBox)
  352.       Gui.FirstOutputBox->previous = ob;
  353.    Gui.FirstOutputBox = ob;
  354.     if (InitialValue)
  355.         SetOutputBoxText(ob, InitialValue);
  356.     else
  357.         SetOutputBoxText(ob, "");
  358.    Diagnostic("MakeOutputBox", EXIT, TRUE);
  359.    return ob;
  360.    }
  361.  
  362. int FOXLIB GetOutputBoxID(REGA0 OutputBox *o)
  363. {
  364.     return o->id;
  365. }
  366.  
  367. OutputBox* FOXLIB SetPreText(REGA0 void *p, REGA1 char *t)
  368. {
  369.     return MakeOutputBox(p, 0, 0, 0, 0, 0, t, OB_PRE | NO_BORDER, NULL);
  370. }
  371.  
  372. OutputBox* FOXLIB SetPostText(REGA0 void *p, REGA1 char *t)
  373. {
  374.     return MakeOutputBox(p, 0, 0, 0, 0, 0, t, OB_POST | NO_BORDER, NULL);
  375. }
  376.